package com.boarsoft.boar.gateway.router;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.boarsoft.cache.Cache;
import com.boarsoft.common.util.InetUtil;
import com.boarsoft.common.util.RandomUtil;
import com.boarsoft.rpc.bean.RpcRegistry;
import com.boarsoft.rpc.bean.RpcServiceConfig;
import com.boarsoft.rpc.core.RpcContext;
import com.boarsoft.rpc.listener.RpcListener;
import com.boarsoft.soagov.route.ServiceRouter;

/**
 * 从mac-rpc获取所有节点的注册信息，以获取HTTP请求应转发的目标地址
 * 
 * @author Mac_J
 *
 */
public class MacRpcHttpRouter implements ServiceRouter<HttpServletRequest>, RpcListener {
	private static final Logger log = LoggerFactory.getLogger(MacRpcHttpRouter.class);

	@Autowired
	protected RpcContext rpcContext;

	protected Cache cache;

	@Override
	public String getProvider(HttpServletRequest req) {
		String sid = (String) req.getAttribute("app");
		List<RpcRegistry> lt = rpcContext.getAllProvidersByKey(sid, false);
		while (lt != null && !lt.isEmpty()) {
			try {
				int size = lt.size();
				RpcRegistry rr = lt.get(size > 1 ? RandomUtil.random(0, lt.size()) : 0);
				String port = rr.getMetaString("http.port", "8080");
				String[] aa = rr.getKey().split(":");
				return new StringBuilder(aa[0]).append(":").append(port).toString();
			} catch (Exception e) {
				log.error("Error on pick provider", e);
			}
		}
		return null;
	}

	public RpcContext getRpcContext() {
		return rpcContext;
	}

	public void setRpcContext(RpcContext rpcContext) {
		this.rpcContext = rpcContext;
	}

	public Cache getCache() {
		return cache;
	}

	public void setCache(Cache cache) {
		this.cache = cache;
	}

	@Override
	public void onRemoveLink(String addr, String reason) {
		// Nothing to do
	}

	@Override
	public void onRegister(RpcRegistry reg) {
		// Nothing to do
	}

	@Override
	public void onDeregister(RpcRegistry reg) {
		// Nothing to do
	}

	@Override
	public void onUpdateRegistry(RpcRegistry rr) {
		String addr = rr.getKey();
		// 不检查自己的注册表
		if (InetUtil.getAddr().equals(addr)) {
			return;
		}
		// 来自远程的serviceMap
		Map<String, RpcServiceConfig> sm = rr.getServiceMap();
		for (String sk : sm.keySet()) {
			log.debug("Found service provider {} -> {}", addr, sk);
			RpcServiceConfig sc = sm.get(sk);
			// 如果服务状态为不可用，则将远程节点放到禁用的服务提供者列表
			if (sc.isEnable()) {
				this.rpcContext.putProvider(rr, sk);
			} else {
				this.rpcContext.putProvider2(rr, sk);
			}
		}
	}

	@Override
	public void config() {
		// TODO Auto-generated method stub
		
	}
}
